﻿Imports System.Collections

Public Class ThreeDElements
    Public _GraphicsDevice As GraphicsDevice
    Public _GameManager As GameManagerCollection

    Public TrianglePicking As Boolean = False
    Public PickedTriangle As VertexPositionColor() = {New VertexPositionColor(Vector3.Zero, Color.Magenta), New VertexPositionColor(Vector3.Zero, Color.Magenta), New VertexPositionColor(Vector3.Zero, Color.Magenta)}
    Public LineEffect As BasicEffect
    Public WireFrame As New RasterizerState() With {.FillMode = FillMode.WireFrame, .CullMode = CullMode.None}
    Public Models As Model() = New Model(ModelFilenames.Length - 1) {}
    Public ModelAbsoluteBoneTransforms As Matrix()() = New Matrix(ModelFilenames.Length - 1)() {}
    Public ModelWorldTransforms As Matrix() = New Matrix(ModelFilenames.Length - 1) {}
    Shared ReadOnly ModelFilenames As String() = {"Terrain", "Lego_Man"}

    Public Sub New(ByVal Game As DanoQuest)
        _GameManager = Game.GameManager
        _GraphicsDevice = Game.GraphicsDevice
        For i As Integer = 0 To ModelWorldTransforms.Length - 1
            Dim x As Single = CSng(i - ModelWorldTransforms.Length / 2)
            If i = 1 Then
                ModelWorldTransforms(i) = Matrix.CreateTranslation(New Vector3(0, 0, 0)) * Matrix.CreateScale(0.05F, 0.05F, 0.05F)
            Else
                ModelWorldTransforms(i) = Matrix.CreateTranslation(New Vector3(0, 0, 0))
            End If
        Next
        For i As Integer = 0 To ModelFilenames.Length - 1
            Models(i) = Game.Content.Load(Of Model)(ModelFilenames(i))
            ModelAbsoluteBoneTransforms(i) = New Matrix(Models(i).Bones.Count - 1) {}
            Models(i).CopyAbsoluteBoneTransformsTo(ModelAbsoluteBoneTransforms(i))
            For Each mesh As ModelMesh In Models(i).Meshes
                For Each effect As BasicEffect In mesh.Effects
                    effect.EnableDefaultLighting()  'Set the default lighting flag, we do not have to set it in every draw loop , so it is set here
                    effect.PreferPerPixelLighting = True
                Next
            Next
        Next
        LineEffect = New BasicEffect(_GraphicsDevice) With {.VertexColorEnabled = True}
    End Sub

    Public Sub Draw()
        _GraphicsDevice.BlendState = BlendState.Opaque
        _GraphicsDevice.DepthStencilState = DepthStencilState.Default
        For i As Integer = 0 To Models.Length - 1
            DrawModel(Models(i), ModelWorldTransforms(i), ModelAbsoluteBoneTransforms(i))
        Next
        If TrianglePicking Then
            _GraphicsDevice.RasterizerState = WireFrame
            _GraphicsDevice.DepthStencilState = DepthStencilState.None
            LineEffect.Projection = _GameManager.Camera.ProjectionMatrix
            LineEffect.View = _GameManager.Camera.ViewMatrix
            LineEffect.CurrentTechnique.Passes(0).Apply()
            _GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, PickedTriangle, 0, 1)
            _GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise
            _GraphicsDevice.DepthStencilState = DepthStencilState.Default
        End If
    End Sub

    Private Sub DrawModel(ByRef Model As Model, ByRef WorldMatrix As Matrix, ByRef AbsoluteBoneTransforms As Matrix())
        For Each Mesh As ModelMesh In Model.Meshes
            For Each Effect As BasicEffect In Mesh.Effects
                Effect.View = _GameManager.Camera.ViewMatrix
                Effect.Projection = _GameManager.Camera.ProjectionMatrix
                Effect.World = AbsoluteBoneTransforms(Mesh.ParentBone.Index) * WorldMatrix
            Next
            Mesh.Draw()
        Next
    End Sub

End Class

























'Imports System.Collections

'Public Class ThreeDElements
'    Inherits Microsoft.Xna.Framework.DrawableGameComponent
'    Public _GraphicsDevice As GraphicsDevice
'    Public _GameManager As GameManagerCollection

'    Public TrianglePicking As Boolean = False
'    Public PickedTriangle As VertexPositionColor() = {New VertexPositionColor(Vector3.Zero, Color.Magenta), New VertexPositionColor(Vector3.Zero, Color.Magenta), New VertexPositionColor(Vector3.Zero, Color.Magenta)}
'    Public LineEffect As BasicEffect
'    Public WireFrame As New RasterizerState() With {.FillMode = FillMode.WireFrame, .CullMode = CullMode.None}
'    Public Models As Model() = New Model(ModelFilenames.Length - 1) {}
'    Public ModelAbsoluteBoneTransforms As Matrix()() = New Matrix(ModelFilenames.Length - 1)() {}
'    Public ModelWorldTransforms As Matrix() = New Matrix(ModelFilenames.Length - 1) {}
'    Shared ReadOnly ModelFilenames As String() = {"Terrain", "Lego_Man"}

'    Public Sub New(ByVal Game As DanoQuest)
'        MyBase.New(Game)
'        Game.Components.Add(Me)
'        _GameManager = Game.GameManager
'        _GraphicsDevice = Game.GraphicsDevice
'        For i As Integer = 0 To ModelWorldTransforms.Length - 1
'            Dim x As Single = CSng(i - ModelWorldTransforms.Length / 2)
'            If i = 1 Then
'                ModelWorldTransforms(i) = Matrix.CreateTranslation(New Vector3(0, 0, 0)) * Matrix.CreateScale(0.05F, 0.05F, 0.05F)
'            Else
'                ModelWorldTransforms(i) = Matrix.CreateTranslation(New Vector3(0, 0, 0))
'            End If
'        Next
'        For i As Integer = 0 To ModelFilenames.Length - 1
'            Models(i) = Game.Content.Load(Of Model)(ModelFilenames(i))
'            ModelAbsoluteBoneTransforms(i) = New Matrix(Models(i).Bones.Count - 1) {}
'            Models(i).CopyAbsoluteBoneTransformsTo(ModelAbsoluteBoneTransforms(i))
'            For Each mesh As ModelMesh In Models(i).Meshes
'                For Each effect As BasicEffect In mesh.Effects
'                    effect.EnableDefaultLighting()  'Set the default lighting flag, we do not have to set it in every draw loop , so it is set here
'                    effect.PreferPerPixelLighting = True
'                Next
'            Next
'        Next
'        LineEffect = New BasicEffect(_GraphicsDevice) With {.VertexColorEnabled = True}
'    End Sub

'    ''' <summary>
'    ''' Allows the game component to perform any initialization it needs to before starting
'    ''' to run.  This is where it can query for any required services and load content.
'    ''' </summary>
'    Public Overrides Sub Initialize()
'        ' TODO: Add your initialization code here
'        MyBase.Initialize()
'    End Sub

'    ''' <summary>
'    ''' Allows the game component to update itself.
'    ''' </summary>
'    ''' <param name="gameTime">Provides a snapshot of timing values.</param>
'    Public Overrides Sub Update(ByVal gameTime As GameTime)
'        MyBase.Update(gameTime)
'    End Sub

'    Public Overrides Sub Draw(gameTime As GameTime)
'        _GraphicsDevice.BlendState = BlendState.Opaque
'        _GraphicsDevice.DepthStencilState = DepthStencilState.Default
'        For i As Integer = 0 To Models.Length - 1
'            DrawModel(Models(i), ModelWorldTransforms(i), ModelAbsoluteBoneTransforms(i))
'        Next
'        If TrianglePicking Then
'            _GraphicsDevice.RasterizerState = WireFrame
'            _GraphicsDevice.DepthStencilState = DepthStencilState.None
'            LineEffect.Projection = _GameManager.Camera.ProjectionMatrix
'            LineEffect.View = _GameManager.Camera.ViewMatrix
'            LineEffect.CurrentTechnique.Passes(0).Apply()
'            _GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, PickedTriangle, 0, 1)
'            _GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise
'            _GraphicsDevice.DepthStencilState = DepthStencilState.Default
'        End If
'    End Sub

'    Private Sub DrawModel(ByRef Model As Model, ByRef WorldMatrix As Matrix, ByRef AbsoluteBoneTransforms As Matrix())
'        For Each Mesh As ModelMesh In Model.Meshes
'            For Each Effect As BasicEffect In Mesh.Effects
'                Effect.View = _GameManager.Camera.ViewMatrix
'                Effect.Projection = _GameManager.Camera.ProjectionMatrix
'                Effect.World = AbsoluteBoneTransforms(Mesh.ParentBone.Index) * WorldMatrix
'            Next
'            Mesh.Draw()
'        Next
'    End Sub


'    'Private Sub DrawModel(Model As Model, scale As Matrix, location As Vector3)
'    '    Game.Components.OfType(Of Camera).ToList.Item(0).worldmatrix = scale * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateTranslation(location) 'Scale, ?, Location
'    '    Dim modelTransforms(Model.Bones.Count) As Matrix
'    '    Model.CopyAbsoluteBoneTransformsTo(modelTransforms)
'    '    For Each mesh As ModelMesh In Model.Meshes
'    '        For Each effect As BasicEffect In mesh.Effects
'    '            effect.World = modelTransforms(mesh.ParentBone.Index) * Game.Components.OfType(Of Camera).ToList.Item(0).worldmatrix
'    '            effect.View = Game.Components.OfType(Of Camera).ToList.Item(0).ViewMatrix
'    '            effect.Projection = Game.Components.OfType(Of Camera).ToList.Item(0).projectionMatrix
'    '            mesh.Draw()
'    '        Next
'    '    Next
'    'End Sub
'End Class

